#pragma once

#include <iostream>
#include <memory>
#include "Epoller.hpp"
#include "Socket.hpp"
#include "Log.hpp"
#include "InetAddr.hpp"
#include "Connection.hpp"
#include "IOService.hpp"
#include "Reactor.hpp"
#include "Protocol.hpp"
#include "Calculator.hpp"

using namespace SocketModule;

// 专门负责获取链接的模块
// 链接管理器
class Listener : public Connection
{
public:
    Listener(int port)
    :_listensock(std::make_unique<TcpSocket>()),
     _port(port) 
    {
        _listensock->BuildTcpSocketMethod(_port);
        SetSockfd(_listensock->Fd());
        SetEvents(EPOLLIN | EPOLLET);

    }
    virtual void Sender() override
    {

    }
    // 有天然父类 connection 
    virtual void Recver() override
    {
        // IO 处理 -- 获取新连接
        while(true)
        {
            InetAddr peer;
            int aerrno = 0;
            // accept 非阻塞的时候, 就是 IO, 我们就向处理 read 一样
            int sockfd = _listensock->Accepter(&peer, &aerrno);
            if(sockfd > 0)
            {
                // success , 但是不能直接读取 的
                // sockfd 只能添加到 epoll , epollserver 只认 connection
                LOG(LogLevel::DEBUG) << "Accepter success" << sockfd;
                // 普通文件描述符 处理 IO 的, 也是 connection

                // 2. sockfd 包装成 Connection
                auto conn = std::make_shared<IOService>(sockfd);
                conn->RegisterOnMessage(HandlerRequest);
                // 3.插入到 EpollServer
                GetOwner()->InsertConnection(conn);
            }
            else
            {
                if(aerrno == EAGAIN || aerrno == EWOULDBLOCK)
                {
                    LOG(LogLevel::DEBUG) << "accepter all connection ... done "; // 连接获取完了
                    break;
                }
                else if(aerrno == EINTR)
                {
                    LOG(LogLevel::DEBUG) << "accepter intr by signal, continue";  
                    continue;
                }
                else
                {
                    LOG(LogLevel::DEBUG) << "accepter error ... Ignore";
                    break;
                }
            }
        }
    }
    virtual void Excepter() override
    {
    }

    void Accepter(std::shared_ptr<Connection> conn) // 连接管理器
    {
        // 读 & listensock 就绪
        // LOG(LogLevel::DEBUG) << "IsLand Accepter";

    }
    int Sockfd() {return _listensock->Fd();}
    ~Listener()
    {
        _listensock->Close();
    }
private:
    std::unique_ptr<Socket> _listensock;
    int _port;
};